package com.fwindpeak.wxluckmoney;

import java.io.IOException;
import java.io.StringReader;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

//https://github.com/veryyoung/WechatLuckyMoney.git
public class MainHook implements IXposedHookLoadPackage {

	public static final String WECHAT_PACKAGE_NAME = "com.tencent.mm";

	// 微信版本号
	private static String wechatVersion = "";

	private String getFromXml(String xmlStr, String key) throws XmlPullParserException, IOException {
		String xml = xmlStr.substring(xmlStr.indexOf("<msg>"));
		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		factory.setNamespaceAware(true);
		XmlPullParser xpp = factory.newPullParser();
		xpp.setInput(new StringReader(xml));
		int eventType = xpp.getEventType();
		String result = "";
		while (eventType != XmlPullParser.END_DOCUMENT) {
			if ((eventType == XmlPullParser.START_TAG) && (xpp.getName().equals(key))) {
				xpp.nextToken();
				result = xpp.getText();
				break;
			}
			eventType = xpp.next();
		}
		return result;
	}

	private boolean isGroupTalk(String talker) {
		return talker.endsWith("@chatroom");
	}

	public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpp) throws Throwable {

		if (lpp.packageName.equals(WECHAT_PACKAGE_NAME)) {

			if (TextUtils.isEmpty(wechatVersion)) {
				Context context = (Context) (Context) XposedHelpers.callMethod(XposedHelpers.callStaticMethod(
						XposedHelpers.findClass("android.app.ActivityThread", null), "currentActivityThread",
						new Object[0]), "getSystemContext", new Object[0]);
				String versionName = context.getPackageManager().getPackageInfo(lpp.packageName, 0).versionName;
				XposedBridge.log("Found wechat version:" + versionName);
				wechatVersion = versionName;
				VersionParam.init(versionName);
			}

			if (!wechatVersion.equals("6.3.18")) {
				return;
			}

			XposedHelpers.findAndHookMethod(VersionParam.getMessageClass, lpp.classLoader, "b", Cursor.class,
					new XC_MethodHook() {
						@Override
						protected void afterHookedMethod(MethodHookParam mhp) throws Throwable {
							if (!PreferencesUtils.open()) {// 抢红包开关
								return;
							}

							int field_type = XposedHelpers.getIntField(mhp.thisObject, "field_type");
							XposedBridge.log("xposed, field_type：" + field_type);
							if ((field_type == 436207665) || (field_type == 469762097)) {

								int status = (Integer) XposedHelpers.getObjectField(mhp.thisObject, "field_status");
								XposedBridge.log("xposed, status：" + status);
								if (status == 4) {
									return;
								}

								int isSend = (Integer) XposedHelpers.getObjectField(mhp.thisObject, "field_isSend");
								XposedBridge.log("xposed, isSend：" + isSend);
								if (PreferencesUtils.notSelf() && isSend != 0) {
									return;
								}

								String talker = (String) XposedHelpers.getObjectField(mhp.thisObject, "field_talker");
								XposedBridge.log("xposed, talker：" + talker);
								if (PreferencesUtils.notWhisper() && !isGroupTalk(talker)) {
									return;
								}

								if (!isGroupTalk(talker) && isSend != 0) {
									return;
								}

								if (isGroupTalk(talker) && PreferencesUtils.notMute()) {
									Object msgInfo = XposedHelpers.callStaticMethod(
											XposedHelpers.findClass("com.tencent.mm.storage.ai", lpp.classLoader), "E",
											mhp.thisObject);
									boolean notMute = (boolean) XposedHelpers.callStaticMethod(XposedHelpers.findClass(
											"com.tencent.mm.booter.notification.c", lpp.classLoader), "a", talker,
											msgInfo, 3, false);
									if (!notMute) {
										return;
									}
								}

								String content = (String) XposedHelpers.getObjectField(mhp.thisObject, "field_content");
								XposedBridge.log("xposed, content：" + content);

								String nativeUrlString = getFromXml(content, "nativeurl");
								Uri localUri = Uri.parse(nativeUrlString);
								int msgType = Integer.parseInt(localUri.getQueryParameter("msgtype"));
								int channelId = Integer.parseInt(localUri.getQueryParameter("channelid"));
								String sendId = localUri.getQueryParameter("sendid");

								Object[] obj = new Object[8];
								obj[0] = Integer.valueOf(msgType);
								obj[1] = Integer.valueOf(channelId);
								obj[2] = sendId;
								obj[3] = nativeUrlString;
								obj[4] = "";
								obj[5] = "";
								obj[6] = talker;
								obj[7] = "v1.0";

								Object ab = XposedHelpers.newInstance(XposedHelpers.findClass(
										"com.tencent.mm.plugin.luckymoney.c.ab", lpp.classLoader), obj);

								int delayTime = PreferencesUtils.delay() ? PreferencesUtils.delayTime() : 0;

								XposedHelpers.callMethod(XposedHelpers.callStaticMethod(
										XposedHelpers.findClass("com.tencent.mm.model.ah", lpp.classLoader),
										VersionParam.getNetworkByModelMethod, new Object[0]), "d", new Object[] { ab });
							}
						}
					});
		}
	}

}
